package com.lagou.edu.factory;

import com.lagou.edu.antation.Autowired;
import com.lagou.edu.antation.Repository;
import com.lagou.edu.antation.Service;
import com.lagou.edu.antation.Transactional;
import com.lagou.edu.service.TransferService;
import com.lagou.edu.utils.Scanner;
import com.lagou.edu.utils.TransactionManager;

import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

/**
 * 注解工厂
 */
public class AntationBeanFactory {
    private static Map<String,Object> map = new HashMap<>();  // 存储对象

    static Scanner scanner = new Scanner();
    static {
        Set<Class<?>> clsList = null;
        try {
            clsList = scanner.getClasses("com.lagou.edu.service");

            if (clsList != null && clsList.size() > 0) {
                for (Class<?> cls : clsList) {
                    if (cls.isAnnotationPresent(Repository.class)) {

                         //1.处理所有Repository
                        doRepositoryIOC(cls);

                    }else if (cls.isAnnotationPresent(Service.class)) {

                        //2.处理所有service
                        doServiceIOC(cls);

                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static void doRepositoryIOC(Class<?> cls ) throws Exception {
           Repository repository = cls.getAnnotation(Repository.class);
           String id = repository.value();
          if(id == null || "".equals(id)) {
            id = cls.getSimpleName();
            id = id.substring(0,1).toLowerCase()+  id.substring(1);
        }
        Object o = cls.newInstance();  // 实例化之后的对象
        map.put(id,o);
    }

    //反射实例化service对象
    private static void doServiceIOC(Class<?> cls ) throws Exception {
           Service service =  cls.getAnnotation(Service.class);
           String id = service.value();
           if(id == null || "".equals(id)) {
               id = cls.getSimpleName();
               id = id.substring(0,1).toLowerCase()+  id.substring(1);
           }
            Object o = cls.newInstance();  // 实例化之后的对象
            map.put(id,o);


            //依赖注入
            Field[] declaredFields = cls.getDeclaredFields();
            for(Field field : declaredFields) {
                if(field.isAnnotationPresent(Autowired.class)) {
                    Autowired autowired =  field.getAnnotation(Autowired.class);

                    String key = autowired.value();
                    Class  type =field.getType();
                    Object instance = map.get(key);
                    // 给filed赋值
                    field.setAccessible(true);
                    field.set(o, instance);

                }
            }

            //事务增强
          if(cls.isAnnotationPresent(Transactional.class)) {
              doTransactional(cls,id);
          }

    }



    //如果有事务，生成代理替换原有bean
    private static void doTransactional(Class cls,String id) {

          ProxyFactory proxyFactory = new ProxyFactory();
          proxyFactory.setTransactionManager(TransactionManager.getInstance());

           Class[] interfaces = cls.getInterfaces();
           Object proxy= null;
           if(interfaces.length >0) {
                proxy =  proxyFactory.getJdkProxy(map.get(id));

           }else{
                proxy =  proxyFactory.getCglibProxy(map.get(id));
           }

            map.put(id,proxy);
    }

    public static  Object getBean(String id) {
        return map.get(id);
    }


    public static void main(String[] args) {
              AntationBeanFactory antationBeanFactory = new AntationBeanFactory();
            TransferService transferService = (TransferService) antationBeanFactory.getBean("transferServiceImpl2");
             System.out.println(transferService);
    }



}
